package com.exercise.algorithm.tree;

import com.fun.frame.SourceCode;

public class BinaryTree extends SourceCode {

    private BinaryTreeNode root;

    public BinaryTree() {

    }

    public BinaryTreeNode getRoot() {
        return this.root;
    }

    public void setRoot(BinaryTreeNode node) {
        this.root = node;
    }

    public void clear(BinaryTreeNode node) {
        if (node != null) {
            clear(node.getLeft());
            clear(node.getRight());
            node = null;
        }
    }

    public void clear() {
        clear(root);
    }

    public boolean isEmpty() {
        return this == null;
    }

    public int height(BinaryTreeNode node) {
        if (node == null) return 0;
        int heigh = height(node.getLeft());
        int heigh1 = height(node.getRight());
        int i = heigh > heigh1 ? heigh : heigh1;
        return i + 1;
    }

    public int size(BinaryTreeNode node) {
        if (node == null) return 0;
        int size = size(node.getLeft());
        int size1 = size(node.getRight());
        return size + size1 + 1;
    }

    public BinaryTreeNode getParent(BinaryTreeNode tree, BinaryTreeNode node) {
        if (tree == null) return null;
        if (tree.getLeft() == node || tree.getRight() == node) return tree;
        BinaryTreeNode parent = getParent(tree.getLeft(), node);
        return parent == null ? getParent(tree.getRight(), node) : parent;
    }

    public BinaryTreeNode getParent(BinaryTreeNode node) {
        if (root == null || root == node) return null;
        return getParent(root, node);
    }

    public void insertLeft(BinaryTreeNode parent, BinaryTreeNode node) {
        parent.setLeft(node);
    }

    public void insertRight(BinaryTreeNode parent, BinaryTreeNode node) {
        parent.setRight(node);
    }

    public void print012(BinaryTreeNode node) {
        if (node != null) {
            output(node.getData());
            print012(node.getLeft());
            print012(node.getRight());
        }
    }

    public void print102(BinaryTreeNode node) {
        if (node != null) {
            print102(node.getLeft());
            output(node.getData());
            print012(node.getRight());
        }
    }

    public void print120(BinaryTreeNode node) {
        if (node != null) {
            print120(node.getLeft());
            print120(node.getRight());
            output(node.getData());
        }
    }

    public void insert(int value) {
        if (root == null) {
            root = new BinaryTreeNode(value);
        } else {
            BinaryTreeNode current = root;
            BinaryTreeNode parent = null;
            while (true) {
                parent = current;
                if (value > current.getData()) {
                    current = current.getRight();
                    if (current == null) {
                        parent.setRight(new BinaryTreeNode(value));
                        return;
                    }
                } else {
                    current = parent.getLeft();
                    if (current == null) {
                        parent.setLeft(new BinaryTreeNode(value));
                        return;
                    }
                }
            }
        }
    }

    public BinaryTreeNode search(int value) {
        BinaryTreeNode current = root;
        if (root == null) return null;
        while (current.getData() != value) {
            if (current.getData() > value) {
                current = current.getLeft();
            } else {
                current = current.getRight();
            }
            if (current == null) return null;
        }
        return current;
    }


}
